<template>
  <div class="Crop">
    <img :src="src" alt="证件照图片" style="display:none;" ref="cropImg" />
    <!-- 画布 -->
    <div class="container">
      <div class="canvasBox">
        <canvas 
          id="cropCan" 
          ref="cropCan"
        ></canvas>
      </div>
      <cut-box 
        :canvasStyle="canvasStyle" 
        :cutParams="cropParam"
        :originSize="originSize"
        :custom="custom"
        ref="cutBox"
        class="cutBox"
      >
      </cut-box>
    </div>
    <!-- 操作区域 -->
    <div class="operation">
      <div class="cropInfo">
        <span>证件照常用尺寸</span>
        <div class="crop-switch">
          裁剪模式
          <van-switch 
            v-model="flag" 
            size="22px"  
            :style="`transform:translate(0,25%); margin-left: 5px;`" 
            @input="flagChange"
            :disabled="custom"
          />
        </div>
        <!-- <i class="iconfont crop-help-icon">&#xe718;</i> -->
      </div>
      <ul class="photoParams">
        <!-- 8 * ? -->
        <li
          v-for="(item,index) in paramsList"
          :key="item.name"
          class="paramItem"
          :class="{
            'active' : cropActive === index
          }"
          @click="selectParam(index)"
        >
          <span>{{ item.name }}</span>
          <span class="itemDes">{{ item.des }}</span>
        </li>
      </ul>
      <div class="cropFooter">
        <span class="footer-confirm" @click="crop()">
          裁剪<i class="iconfont">&#xe663;</i>
        </span>
        <!-- 旋转/翻转 -->
        <div>
          <span @click="ctxRotate(-1)">
            <i class="iconfont footer-confirm" style="font-size: 16px">&#xe6ba;</i>
          </span>
          <!-- 水平翻转 -->
          <span :class="{
            flip : !rotateType
          }" style="transition:all .3s; opacity : 0;"  @click="flip(1)">
            <i class="iconfont footer-confirm" style="font-size: 16px; margin: 0 15px">&#xe630;</i>
          </span>
          <span  @click="ctxRotate(1)">
            <i class="iconfont footer-confirm" style="font-size: 16px">&#xe6bb;</i>
          </span>
        </div>
        <span class="footer-next" @click="toBgHandle()">
          下一步<i class="iconfont">&#xe683;</i>
        </span>
      </div>
    </div>
  </div>
</template>

<script>
import CutBox from "../components/CuttingBox"

export default {
  name: "Crop",
  components: {
    CutBox
  },
  data() {
    return {
      src: "",
      paramsList: [
        {
          name: "自定义",
          des: "",
          paramX: '',
          paramY: '',
          pxX : '',
          pxY : ''
        },
        {
          name: "小一寸",
          des: "22 * 32mm",
          paramX: 22,
          paramY: 32,
          pxX : 259,
          pxY : 377
        },
        {
          name: "一寸",
          des: "25 * 35mm",
          paramX: 25,
          paramY: 35,
          pxX : 295,
          pxY : 413
        },
        {
          name: "大一寸",
          des: "33 * 48mm",
          paramX: 33,
          paramY: 48,
          pxX : 389,
          pxY : 566
        },
        {
          name: "小二寸",
          des: "35 * 45mm",
          paramX: 35,
          paramY: 45,
          pxX : 413,
          pxY : 531
        },
        {
          name: "二寸",
          des: "22 * 33mm",
          paramX: 35,
          paramY: 49,
          pxX : 413,
          pxY : 579
        },
        {
          name: "大二寸",
          des: "35 * 53mm",
          paramX: 35,
          paramY: 53,
          pxX : 413,
          pxY : 625
        },
        {
          name: "四六级",
          des: "24 * 32mm",
          paramX: 24,
          paramY: 32,
          pxX: 168,
          pxY: 224
        },
        {
          name: "医保证",
          des: "26 * 32mm",
          paramX: 26,
          paramY: 32,
          pxX : 306,
          pxY : 377
        },
        {
          name: "驾驶证",
          des: "22 * 32mm",
          paramX: 22,
          paramY: 32,
          pxX : 259,
          pxY : 377
        }
      ],
      cropActive: 1,
      canvasStyle : {},
      originSize : [],
      flag: true,
      rotateType : 0,
      rotateSize : [],
      rotateShow : true,
      custom : false
    };
  },
  methods: {
    // 加载图片，并将图片存入到canvas中
    async loadImg(src) {
      this.src = src; // 拿到image的数据
      let cropCan = this.$refs.cropCan; // dom操作
      let cropImg = this.$refs.cropImg;
      let self = this;
      cropImg.onload = await function() {
        self.imgToCanvas(cropImg, cropCan);
        self.originSize = [cropCan.width,cropCan.height];
        self.rotateSize = [cropCan.width,cropCan.height];
        console.log('加载图像,图像原始尺寸：',self.originSize);
        self.canvasStyle = self.$refs.cropCan.getBoundingClientRect();
        // 避免裁剪后再此加载图片，图像存储的数据出现bug
        self.$refs.cropImg = cropImg;
      };
    },
    // 图片数据转到canvas画布上
    imgToCanvas(img, canvas) {
      canvas.width = img.width;
      canvas.height = img.height;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0);
    },
    // 转换
    canvasToImg(canvas) {
        // Converts canvas to an image
        var image = new Image();
        let data = canvas.toDataURL("image/png");
        // console.log(data); // 显示数据大小
        image.src = data;
        return image;
    },
    // 选择证件照尺寸
    selectParam(index) {
      if(index === 0) {
        this.custom = true;
        this.flag = false;
      }else {
        this.custom = false;
        this.flag = true;
      }
      this.cropActive = index;
    },
    // 获取当前画布数据
    getMomentCanData(){
      let canvas = this.$refs.cropCan;
      let styleRes = window.getComputedStyle(canvas);
      let domWidth = parseFloat(styleRes.getPropertyValue('width'));
      let domHeight = parseFloat(styleRes.getPropertyValue('height'));
      let width = canvas.width;
      let height = canvas.height;
      console.log('dom/canvas',domWidth,domHeight,width,height);
      let ctx = canvas.getContext('2d');
      let data = ctx.getImageData(0,0,canvas.width,canvas.height);
      console.log(data);
      this.$store.state.cropData = { data, width, height };
    },
    clip(canvas){
      let canvasCutData = this.$refs.cutBox.canvasCutData;
      console.log(canvasCutData);
      let ctx = canvas.getContext('2d');
      // 画布区域
      let cutData = ctx.getImageData(canvasCutData.left,canvasCutData.top,canvasCutData.width,canvasCutData.height);
      // 画布渲染
      console.log(cutData);
      canvas.width = canvasCutData.width;
      canvas.height = canvasCutData.height;
      ctx.putImageData(cutData,0,0);

      let img = this.canvasToImg(canvas);
      
      // 是否进行压缩裁剪
      if(this.flag){
        let pxX = canvasCutData.cutParams.pxX;
        let pxY = canvasCutData.cutParams.pxY;
        canvas.width = pxX;
        canvas.height = pxY;
        let ctx2 = canvas.getContext('2d');
        let self = this;
        img.onload = function() {  // 等待图片加载完成后，进行裁剪
          ctx2.drawImage(img,0,0,pxX,pxY);
          // 解决裁剪完后旋转出现的问题
          img = self.canvasToImg(canvas);
          self.$refs.cropImg = img;
        }
      }else {
        this.$refs.cropImg = img;
      }
      // this.rotateShow = false;
    },
    // 裁剪按钮
    crop(){
      let canvas = this.$refs.cropCan;
      this.clip(canvas);
      this.originSize = [canvas.width,canvas.height];
      this.rotateSize = [canvas.width,canvas.height];
      this.canvasStyle = canvas.getBoundingClientRect();
      this.getMomentCanData();
    },
    // 裁剪模式切换
    flagChange() {
      let msg = this.flag ? '按照所给尺寸大小进行裁剪\n图像有一定压缩' : '按照裁剪框比例进行裁剪\n保留原图质量';
      this.$toast({
        message : msg,
      });
    },
    // 页面跳转至背景处理
    toBgHandle() {
      // this.$store.state.cropData = '';
      this.getMomentCanData();
      this.$router.push('/BgHandle');
    },
    // 旋转图像
    ctxRotate(type) {
      this.rotateType += type;
      if(this.rotateType === 4) this.rotateType = 0;
      if(this.rotateType === -1) this.rotateType = 3;
      let width = this.rotateSize[0];
      let height = this.rotateSize[1];
      let img = this.$refs.cropImg;
      let canvas = this.$refs.cropCan;
      let ctx = canvas.getContext('2d');
      let drawArr = [[0,0],[0,-height],[-width ,-height],[-width,0]]
      if(this.rotateType % 2){
        canvas.width = height;
        canvas.height = width;
      }else {
        canvas.height = height;
        canvas.width = width;
      }
      ctx.rotate(this.rotateType * (Math.PI / 2));
      console.log(canvas.width,canvas.height);
      ctx.drawImage(img,...drawArr[this.rotateType]);
      this.originSize = [canvas.width,canvas.height];
      this.canvasStyle = canvas.getBoundingClientRect();
    },
    flip(){
      if(this.rotateType !== 0) return;
      console.log(11);
      let canvas = this.$refs.cropCan;
      let width = this.rotateSize[0];
      let height = this.rotateSize[1];
      let ctx = canvas.getContext('2d');
      let drawArr = [[0,0],[-width, - height],[-width ,-height],[-width,0]]
      ctx.translate(canvas.width, 0);
      ctx.scale(-1, 1);
      ctx.drawImage(this.$refs.cropImg,...drawArr[this.rotateType])
    }
  },
  mounted() {
    // 加载图片
    let self = this;
    if(!this.$store.state.imgSrc){
      this.$router.push('/')
      return
    }
    this.loadImg(self.$store.state.imgSrc);
},
  computed : {
    cropParam(){
      let cutWidth = this.paramsList[this.cropActive].paramX;
      let cutHeight = this.paramsList[this.cropActive].paramY;
      let pxX = this.paramsList[this.cropActive].pxX;
      let pxY = this.paramsList[this.cropActive].pxY;
      return { cutWidth , cutHeight , pxX , pxY  }
    },
  },
  watch: {
    // 监听数据仓库变化，更改照片信息
    "$store.state.imgSrc": function() {
      this.loadImg(this.$store.state.imgSrc);
    },
    
  }
};
</script>

<style scoped>
.Crop {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  height: calc(100% - 46px);
}

.container {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 60%;
}

.container .canvasBox {
  box-shadow: 0 0 9px #999;
}

.container .canvasBox canvas {
  display: block;
  max-height: 50vh;
  max-width: 90vw;
}

.operation {
  background-color: #fff;
  box-shadow: -3px 0 10px #bbb;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.operation .cropInfo {
  width: 95vw;
  display: flex;
  line-height: 45px;
  justify-content: space-between;
}

.operation .cropInfo .crop-help-icon {
  font-size: 16px;
  color: #aaa;
}

.operation .photoParams {
  /* max-height: calc(8 * ?) */
  width: 100vw;
  max-height: calc(4 * 36px);
  overflow: scroll;
  border-bottom: 1px solid #eee;
}

.operation .photoParams .paramItem {
  display: flex;
  justify-content: space-between;
  line-height: 30px;
  font-size: 16px;
  padding: 5px 45px;
  transition: all 0.5s;
}

.operation .photoParams .paramItem .itemDes {
  font-size: 14px;
  color: #888;
}

.operation .photoParams .paramItem.active {
  font-weight: 600;
  color: rgb(0, 102, 255);
  background-color: #f5f7fa;
}

/* 截图操作底部布局 */
.operation .cropFooter {
  width: 100vw;
  height: 55px;
  line-height: 55px;
  padding: 0 3vw;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
}

.operation .cropFooter .footer-next,
.operation .cropFooter .footer-confirm {
  color: rgb(0, 102, 255);
  transition: all .2s;
  padding: 0 6px;
  border-radius: 10px;
}

.operation .cropFooter .footer-confirm>i{
  font-size: 18px;
  padding-left: 5px;
}

.operation .cropFooter .footer-next:active,
.operation .cropFooter .footer-confirm:active {
  font-weight: 600;
  font-size: 17px;
  color: #888;
}

.operation .cropFooter .footer-next>i{
  font-size: 14px;
  padding-left: 5px;
}

.cutBox {
  position: absolute;
  top: 0;
  left: 0;
}

.flip {
  opacity: 1 !important;
}
</style>
